package org.opens.util;

import cn.hutool.core.collection.CollectionUtil;
import org.hibernate.validator.HibernateValidator;

import javax.validation.ConstraintViolation;
import javax.validation.Path;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.*;
import java.util.stream.Collectors;

public class ValidUtil {

    private static final Validator validatorFast = Validation.byProvider(HibernateValidator.class)
            .configure()
            .failFast(true)
            .buildValidatorFactory()
            .getValidator();

    private static final Validator validatorAll = Validation.byProvider(HibernateValidator.class)
            .configure()
            .failFast(false)
            .buildValidatorFactory()
            .getValidator();

    /**
     * 校验遇到第一个不合法的字段直接返回不合法字段，后续字段不再校验
     */
    public static <T> Set<ConstraintViolation<T>> validateFast(T domain) throws Exception {
        Set<ConstraintViolation<T>> validateResult = validatorFast.validate(domain);
        if (validateResult.size() > 0) {
            //System.out.println(validateResult.iterator().next().getPropertyPath() + "：" + validateResult.iterator().next().getMessage());
        }
        return validateResult;
    }

    /**
     * 校验所有字段并返回不合法字段
     */
    public static <T> Set<ConstraintViolation<T>> validateAll(T domain) throws Exception {
        Set<ConstraintViolation<T>> validateResult = validatorAll.validate(domain);
        if (validateResult.size() > 0) {
            Iterator<ConstraintViolation<T>> it = validateResult.iterator();
            while (it.hasNext()) {
                ConstraintViolation<T> cv = it.next();
                //System.out.println(cv.getPropertyPath() + "：" + cv.getMessage());
            }
        }
        return validateResult;
    }

    /**
     * 校验遇到第一个不合法的字段直接返回不合法字段，后续字段不再校验, 并将结果集转换为Map
     */
    public static <T> Map<Path, String> validateFastToMap(T domain) throws Exception {
        Set<ConstraintViolation<T>> constraintViolations = validateFast(domain);
        Map<Path, String> collect = null;
        if (CollectionUtil.isNotEmpty(constraintViolations)) {
            collect = constraintViolations.stream().collect(Collectors.toMap(ConstraintViolation::getPropertyPath, ConstraintViolation::getMessage, (x, y) -> x));
        }
        return collect;
    }

    /**
     * 校验所有字段并返回不合法字段, 并将结果集转换为Map
     */
    public static <T> Map<Path, String> validateAllToMap(T domain) throws Exception {
        Set<ConstraintViolation<T>> constraintViolations = validateAll(domain);
        Map<Path, String> collect = null;
        if (CollectionUtil.isNotEmpty(constraintViolations)) {
            collect = constraintViolations.stream().collect(Collectors.toMap(ConstraintViolation::getPropertyPath, ConstraintViolation::getMessage, (x, y) -> x));
        }
        return collect;
    }

}
